<?php

namespace http;

use GuzzleHttp\Promise as P;
use Psr\Log\LoggerInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Exception\RequestException;

class Middleware
{
    /**
     * @param LoggerInterface $logger
     * @param string $traceId
     * @return callable
     */
    static public function log(LoggerInterface $logger, string $traceId): callable
    {
        return function (callable $handler) use ($traceId, $logger) {
            return static function (RequestInterface $request, array $options = []) use ($handler, $logger, $traceId) {
                return $handler($request, $options)->then(
                    static function(ResponseInterface $response) use ($request, $options, $logger, $traceId): ResponseInterface {
                        $logger->info($traceId, MessageFormatter::format($request, $response));
                        return $response;
                    },
                    static function ($reason) use ($request, $logger, $traceId): PromiseInterface {
                        $response = $reason instanceof RequestException ? $reason->getResponse() : null;
                        $logger->error($traceId, MessageFormatter::format($request, $response, P\Create::exceptionFor($reason)));
                        return P\Create::rejectionFor($reason);
                    }
                );
            };
        };
    }

}
